package com.bangwz.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class Server {

	// 通道管理器
	private Selector selector;

	private ServerSocketChannel server;

	public static void main(String[] args) throws IOException {
		new Server().init().listen();
	}

	public Server init() throws IOException {
		// 打开服务器通道
		server = ServerSocketChannel.open();
		server.configureBlocking(false);

		// 绑定端口
		server.socket().bind(new InetSocketAddress(9527));

		selector = Selector.open();
		// 将通道管理器与通道绑定，并为该通道注册SelectionKey.OP_ACCEPT事件，
		// 只有当该事件到达时，Selector.select()会返回，否则一直阻塞。
		server.register(selector, SelectionKey.OP_ACCEPT);
		return this;
	}

	public void listen() throws IOException {
		while (true) {
			int select = selector.select();
			if (select == 0) {
				continue;
			}
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while (iterator.hasNext()) {
				SelectionKey key = iterator.next();
				// 连接请求
				if (key.isAcceptable()) {
					SocketChannel client = server.accept();
					client.configureBlocking(false);
					client.write(ByteBuffer.wrap(new String("send message to client").getBytes()));
					// 在与客户端连接成功后，为客户端通道注册SelectionKey.OP_READ事件。
					client.register(selector, SelectionKey.OP_READ);
				} else if (key.isReadable()) {// 有可读数据事件
					// 获取客户端传输数据可读取消息通道。
					SocketChannel channel = (SocketChannel) key.channel();
					// 创建读取数据缓冲器
					ByteBuffer buffer = ByteBuffer.allocate(1024);
					int read = channel.read(buffer);
					byte[] data = buffer.array();
					String message = new String(data);

					System.out.println("receive message from client, size:" + buffer.position() + " msg: " + message);
					ByteBuffer outbuffer = ByteBuffer.wrap(("server."
							.concat("receive message from client, size:" + buffer.position() + " msg: " + message))
									.getBytes());
					channel.write(outbuffer);
				}
				iterator.remove();
			}
		}
	}
}
